package org.apache.james.mime4j.field.address;

import java.util.ArrayList;
import java.util.Iterator;
import org.apache.james.mime4j.decoder.DecoderUtil;
import org.apache.james.mime4j.field.address.parser.ASTaddr_spec;
import org.apache.james.mime4j.field.address.parser.ASTaddress;
import org.apache.james.mime4j.field.address.parser.ASTaddress_list;
import org.apache.james.mime4j.field.address.parser.ASTangle_addr;
import org.apache.james.mime4j.field.address.parser.ASTdomain;
import org.apache.james.mime4j.field.address.parser.ASTgroup_body;
import org.apache.james.mime4j.field.address.parser.ASTlocal_part;
import org.apache.james.mime4j.field.address.parser.ASTmailbox;
import org.apache.james.mime4j.field.address.parser.ASTname_addr;
import org.apache.james.mime4j.field.address.parser.ASTphrase;
import org.apache.james.mime4j.field.address.parser.ASTroute;
import org.apache.james.mime4j.field.address.parser.Node;
import org.apache.james.mime4j.field.address.parser.SimpleNode;
import org.apache.james.mime4j.field.address.parser.Token;

class Builder
{
  private static Builder singleton = new Builder();

  private void addSpecials(StringBuffer paramStringBuffer, Token paramToken)
  {
    if (paramToken != null)
    {
      addSpecials(paramStringBuffer, paramToken.specialToken);
      paramStringBuffer.append(paramToken.image);
    }
  }

  private Mailbox buildAddrSpec(DomainList paramDomainList, ASTaddr_spec paramASTaddr_spec)
  {
    ChildNodeIterator localChildNodeIterator = new ChildNodeIterator(paramASTaddr_spec);
    return new Mailbox(paramDomainList, buildString((ASTlocal_part)localChildNodeIterator.nextNode(), true), buildString((ASTdomain)localChildNodeIterator.nextNode(), true));
  }

  private Mailbox buildAddrSpec(ASTaddr_spec paramASTaddr_spec)
  {
    return buildAddrSpec(null, paramASTaddr_spec);
  }

  private Address buildAddress(ASTaddress paramASTaddress)
  {
    Object localObject;
    ChildNodeIterator localChildNodeIterator = new ChildNodeIterator(paramASTaddress);
    Node localNode1 = localChildNodeIterator.nextNode();
    if (localNode1 instanceof ASTaddr_spec)
      localObject = buildAddrSpec((ASTaddr_spec)localNode1);
    while (true)
    {
      String str;
      Node localNode2;
      while (true)
      {
        while (true)
        {
          return localObject;
          if (!(localNode1 instanceof ASTangle_addr))
            break;
          localObject = buildAngleAddr((ASTangle_addr)localNode1);
        }
        if (!(localNode1 instanceof ASTphrase))
          break label151;
        str = buildString((ASTphrase)localNode1, false);
        localNode2 = localChildNodeIterator.nextNode();
        if (!(localNode2 instanceof ASTgroup_body))
          break;
        localObject = new Group(str, buildGroupBody((ASTgroup_body)localNode2));
      }
      if (!(localNode2 instanceof ASTangle_addr))
        break;
      localObject = new NamedMailbox(DecoderUtil.decodeEncodedWords(str), buildAngleAddr((ASTangle_addr)localNode2));
    }
    throw new IllegalStateException();
    label151: throw new IllegalStateException();
  }

  private Mailbox buildAngleAddr(ASTangle_addr paramASTangle_addr)
  {
    ChildNodeIterator localChildNodeIterator = new ChildNodeIterator(paramASTangle_addr);
    DomainList localDomainList = null;
    Node localNode = localChildNodeIterator.nextNode();
    if (localNode instanceof ASTroute)
    {
      localDomainList = buildRoute((ASTroute)localNode);
      localNode = localChildNodeIterator.nextNode();
    }
    do
    {
      if (!(localNode instanceof ASTaddr_spec))
        break label76;
      return buildAddrSpec(localDomainList, (ASTaddr_spec)localNode);
    }
    while (localNode instanceof ASTaddr_spec);
    throw new IllegalStateException();
    label76: throw new IllegalStateException();
  }

  private MailboxList buildGroupBody(ASTgroup_body paramASTgroup_body)
  {
    ArrayList localArrayList = new ArrayList();
    ChildNodeIterator localChildNodeIterator = new ChildNodeIterator(paramASTgroup_body);
    while (true)
    {
      if (!(localChildNodeIterator.hasNext()))
        break label63;
      Node localNode = localChildNodeIterator.nextNode();
      if (!(localNode instanceof ASTmailbox))
        break;
      localArrayList.add(buildMailbox((ASTmailbox)localNode));
    }
    throw new IllegalStateException();
    label63: return new MailboxList(localArrayList, true);
  }

  private Mailbox buildMailbox(ASTmailbox paramASTmailbox)
  {
    Object localObject;
    Node localNode = new ChildNodeIterator(paramASTmailbox).nextNode();
    if (localNode instanceof ASTaddr_spec)
      localObject = buildAddrSpec((ASTaddr_spec)localNode);
    while (true)
    {
      while (true)
      {
        return localObject;
        if (!(localNode instanceof ASTangle_addr))
          break;
        localObject = buildAngleAddr((ASTangle_addr)localNode);
      }
      if (!(localNode instanceof ASTname_addr))
        break;
      localObject = buildNameAddr((ASTname_addr)localNode);
    }
    throw new IllegalStateException();
  }

  private NamedMailbox buildNameAddr(ASTname_addr paramASTname_addr)
  {
    ChildNodeIterator localChildNodeIterator = new ChildNodeIterator(paramASTname_addr);
    Node localNode1 = localChildNodeIterator.nextNode();
    if (localNode1 instanceof ASTphrase)
    {
      String str = buildString((ASTphrase)localNode1, false);
      Node localNode2 = localChildNodeIterator.nextNode();
      if (!(localNode2 instanceof ASTangle_addr))
        break label76;
      return new NamedMailbox(DecoderUtil.decodeEncodedWords(str), buildAngleAddr((ASTangle_addr)localNode2));
    }
    throw new IllegalStateException();
    label76: throw new IllegalStateException();
  }

  private DomainList buildRoute(ASTroute paramASTroute)
  {
    ArrayList localArrayList = new ArrayList(paramASTroute.jjtGetNumChildren());
    ChildNodeIterator localChildNodeIterator = new ChildNodeIterator(paramASTroute);
    while (true)
    {
      if (!(localChildNodeIterator.hasNext()))
        break label68;
      Node localNode = localChildNodeIterator.nextNode();
      if (!(localNode instanceof ASTdomain))
        break;
      localArrayList.add(buildString((ASTdomain)localNode, true));
    }
    throw new IllegalStateException();
    label68: return new DomainList(localArrayList, true);
  }

  private String buildString(SimpleNode paramSimpleNode, boolean paramBoolean)
  {
    Token localToken1 = paramSimpleNode.firstToken;
    Token localToken2 = paramSimpleNode.lastToken;
    StringBuffer localStringBuffer = new StringBuffer();
    while (true)
    {
      do
      {
        if (localToken1 == localToken2)
          break label58;
        localStringBuffer.append(localToken1.image);
        localToken1 = localToken1.next;
      }
      while (paramBoolean);
      addSpecials(localStringBuffer, localToken1.specialToken);
    }
    label58: localStringBuffer.append(localToken2.image);
    return localStringBuffer.toString();
  }

  public static Builder getInstance()
  {
    return singleton;
  }

  public AddressList buildAddressList(ASTaddress_list paramASTaddress_list)
  {
    ArrayList localArrayList = new ArrayList();
    for (int i = 0; i < paramASTaddress_list.jjtGetNumChildren(); ++i)
      localArrayList.add(buildAddress((ASTaddress)paramASTaddress_list.jjtGetChild(i)));
    return new AddressList(localArrayList, true);
  }

  private static class ChildNodeIterator
  implements Iterator
  {
    private int index;
    private int len;
    private SimpleNode simpleNode;

    public ChildNodeIterator(SimpleNode paramSimpleNode)
    {
      this.simpleNode = paramSimpleNode;
      this.len = paramSimpleNode.jjtGetNumChildren();
      this.index = 0;
    }

    public boolean hasNext()
    {
      int i;
      if (this.index < this.len)
        i = 1;
      while (true)
      {
        return i;
        i = 0;
      }
    }

    public Object next()
    {
      return nextNode();
    }

    public Node nextNode()
    {
      SimpleNode localSimpleNode = this.simpleNode;
      int i = this.index;
      this.index = (i + 1);
      return localSimpleNode.jjtGetChild(i);
    }

    public void remove()
    {
      throw new UnsupportedOperationException();
    }
  }
}